﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace SmartMD.DataAccess.Service
{
    /// <summary>
    /// 通用查询中的查询条件定义
    /// </summary>
    public class Query
    {
        /// <summary>
        /// 查询对应的后台的实体名称
        /// </summary>
        /// <param name="en"></param>
        public Query(string en)
        {
            entityName = en;
        }

        private string entityName;
        private QueryCondition _condition;
        private List<OrderExpression> _orderExpressions;

        /// <summary>
        /// 查询条件
        /// </summary>
        public QueryCondition Condition
        {
            get
            {
                if (_condition == null)
                    _condition = new QueryCondition();
                return _condition;
            }
            set { _condition = value; }
        }

        /// <summary>
        /// 排序表达式集合
        /// </summary>
        public List<OrderExpression> OrderExpressions
        {
            get
            {
                if (_orderExpressions == null)
                    _orderExpressions = new List<OrderExpression>();
                return _orderExpressions;
            }
            set { _orderExpressions = value; }
        }

        /// <summary>
        /// 返回查询XML字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            XElement root = new XElement("rootCondition", new XAttribute("entityName", entityName));

            if (Condition != null)
            {
                //root.Add(Condition.Expressions.Select(qe => GetQueryExpressionElement(qe)));

                XElement conElement = GetConditionElement(Condition);

                if (conElement.FirstNode != null && !string.IsNullOrEmpty(conElement.FirstNode.ToString()))
                {
                    root.Add(conElement);
                }
            }

            if (OrderExpressions != null)
            {
                root.Add(OrderExpressions.Select(oe => GetOrderElement(oe)));
            }

            return root.ToString();
        }

        /// <summary>
        /// 获取查询表达式的XElemet表示
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        private XElement GetQueryExpressionElement(QueryExpression exp)
        {
            XElement e = new XElement(exp.Name,
                new XAttribute("value", exp.Value),
                new XAttribute("operate", exp.RelationOperator == null ? "" : exp.RelationOperator),
                new XAttribute("type", exp.Type));

            if (!string.IsNullOrEmpty(exp.LogicalOperator))
            {
                e.Add(new XAttribute("operation", exp.LogicalOperator));
            }

            return e;
        }

        /// <summary>
        /// 获取查询条件的XElement表示
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        private XElement GetConditionElement(QueryCondition condition)
        {
            XElement conElement = new XElement("condition");
            IEnumerable<XElement> listXElement = new List<XElement>();

            if (condition.Expressions != null && condition.Expressions.Count > 0)
            {
                conElement.Add(condition.Expressions.Select(qe => GetQueryExpressionElement(qe)));
            }

            if (condition.Conditions != null && condition.Conditions.Count > 0)
            {
                listXElement = condition.Conditions.Select(qc => GetConditionElement(qc));
                if (listXElement.Count() > 0)
                {
                    if (listXElement.First().FirstNode != null)  //   ldc   2010-06-28
                    {
                        if (!string.IsNullOrEmpty(listXElement.First().FirstNode.ToString()))
                        {
                            conElement.Add(listXElement);
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(condition.LogicalOperator))
            {
                conElement.Add(new XAttribute("operation", condition.LogicalOperator));
            }

            return conElement;
        }

        /// <summary>
        /// 获取Order表达式的XElement表示
        /// </summary>
        /// <param name="oe"></param>
        /// <returns></returns>
        private XElement GetOrderElement(OrderExpression oe)
        {
            return new XElement(oe.Name, new XAttribute("value", oe.Value), new XAttribute("operate", "order"));
        }
    }

    /// <summary>
    /// 关系运算符定义
    /// </summary>
    public static class RelationOperator
    {
        /// <summary>
        /// 大于等于
        /// </summary>
        public const string GreatEqual = "ge";

        /// <summary>
        /// 大于
        /// </summary>
        public const string GreatThan = "gt";

        /// <summary>
        /// 小于等于
        /// </summary>
        public const string LessEqual = "le";

        /// <summary>
        /// 小于
        /// </summary>
        public const string LessThan = "lt";

        /// <summary>
        /// 等于
        /// </summary>
        public const string Equal = "equal";

        /// <summary>
        /// 不等于
        /// </summary>
        public const string NotEqual = "notequal";

        /// <summary>
        /// 空
        /// </summary>
        public const string Null = "null";

        /// <summary>
        /// 不为空
        /// </summary>
        public const string NotNull = "notnull";

        /// <summary>
        /// 相似
        /// </summary>
        public const string Like = "like";

        /// <summary>
        /// 以字符开始
        /// </summary>
        public const string BeginLike = "beginlike";

        /// <summary>
        /// 以字符结束
        /// </summary>
        public const string EndLike = "endlike";

        /// <summary>
        /// 包含关系
        /// </summary>
        public const string In = "in";
    }

    /// <summary>
    /// 逻辑运算符
    /// </summary>
    public static class LogicalOperator
    {
        /// <summary>
        /// 与
        /// </summary>
        public const string And = "and";

        /// <summary>
        /// 或
        /// </summary>
        public const string Or = "or";
    }

    /// <summary>
    /// 排序顺序
    /// </summary>
    public enum QueryOrder
    {
        Asc, Desc
    }

    /// <summary>
    /// 查询字段的数据类型
    /// </summary>
    public static class QueryDataType
    {
        /// <summary>
        /// 字符串
        /// </summary>
        public const string String = "string";

        /// <summary>
        /// 数值型
        /// </summary>
        public const string Number = "number";

        /// <summary>
        /// 日期
        /// </summary>
        public const string Date = "date";

        public const string DateTime = "DateTime";
    }

    /// <summary>
    /// 查询表达式
    /// </summary>
    public class QueryExpression
    {
        public QueryExpression()
        {
            this.Type = QueryDataType.String;
            this.RelationOperator = Service.RelationOperator.Equal;
        }

        private string _name;

        /// <summary>
        /// 字段名称
        /// </summary>
        public string Name
        {
            get { return _name == null ? null : _name; }
            set { _name = value; }
        }

        /// <summary>
        /// 字段值
        /// </summary>
        public string Value { get; set; }

        /// <summary>
        /// 字段类型
        /// </summary>
        public string Type { get; set; }

        /// <summary>
        /// 关系运算符
        /// </summary>
        public string RelationOperator { get; set; }

        /// <summary>
        /// 逻辑运算符
        /// </summary>
        public string LogicalOperator { get; set; }

        public QueryExpression Copy()
        {
            QueryExpression item = new QueryExpression
            {
                Name = this.Name,
                Value = this.Value,
                Type = this.Type,
                RelationOperator = this.RelationOperator,
                LogicalOperator = this.LogicalOperator
            };
            return item;
        }
    }

    /// <summary>
    /// 查询条件定义
    /// </summary>
    public class QueryCondition
    {
        private List<QueryExpression> _expressions;

        private List<QueryCondition> _conditions;

        /// <summary>
        /// 逻辑运算符
        /// </summary>
        public string LogicalOperator { get; set; }

        /// <summary>
        /// 查询表达式
        /// </summary>
        public List<QueryExpression> Expressions
        {
            get
            {
                if (_expressions == null)
                    _expressions = new List<QueryExpression>();
                return _expressions;
            }
            set { _expressions = value; }
        }

        /// <summary>
        /// 查询条件
        /// </summary>
        public List<QueryCondition> Conditions
        {
            get
            {
                if (_conditions == null)
                    _conditions = new List<QueryCondition>();
                return _conditions;
            }
            set { _conditions = value; }
        }
    }

    /// <summary>
    /// 排序表达式
    /// </summary>
    public class OrderExpression
    {
        public OrderExpression(string name, QueryOrder value)
        {
            this.Name = name;
            this.Value = value;
        }

        /// <summary>
        /// 字段名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 排序标识
        /// </summary>
        public QueryOrder Value { get; set; }
    }
}
